package com.best.oasis.settlement.service.base;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.best.oasis.settlement.common.entity.base.BaseEntity;
import com.best.oasis.settlement.dao.base.BaseDao;
import com.best.oasis.settlement.util.orika.OrikaBeanMapper;
import com.best.oasis.settlement.util.page.BasePageSO;
import com.best.oasis.settlement.util.page.PageList;

public abstract class BaseServiceImpl<T extends BaseEntity, VO, PK extends Serializable> implements BaseService<T, VO, PK> {
	  /**
     * Logger for this class
     */
    protected final Log logger = LogFactory.getLog(getClass());

    protected BaseDao<T, PK> baseDao;
    @SuppressWarnings({ "rawtypes" })
    protected Class entityClass;
    @SuppressWarnings({ "rawtypes" })
    protected Class entityVOClass;
    
    protected OrikaBeanMapper orikaBeanMapper;
    
    /**
     * 请在这里给baseDao，modelClass和modelVOClass赋值
     * eg.
     *      UserServiceImpl.java:
     *              @PostConstruct
     *              public void afterConstruct(){
     *                  super.setBaseDao(userDao);
     *                  super.setModelClass(user.class);
     *                  super.setModelVOClass(userVO.class);
     *              }
     */
    @PostConstruct
    abstract public void afterConstruct();
    
    public void setBaseDao(BaseDao<T, PK> baseDao) {
        this.baseDao = baseDao;
    }

    @SuppressWarnings({ "rawtypes" })
	public Class getEntityClass() {
        return entityClass;
    }

    @SuppressWarnings({ "rawtypes" })
	public void setEntityClass(Class entityClass) {
        this.entityClass = entityClass;
    }

    @SuppressWarnings({ "rawtypes" })
	public Class getEntityVOClass() {
        return entityVOClass;
    }

    @SuppressWarnings({ "rawtypes" })
	public void setEntityVOClass(Class entityVOClass) {
        this.entityVOClass = entityVOClass;
    }

    @Autowired
    public void setOrikaBeanMapper(OrikaBeanMapper orikaMapper) {
        this.orikaBeanMapper = orikaMapper;
    }
    
    public boolean exists(PK id) {
        return baseDao.exists(id);
    }

    @SuppressWarnings("unchecked")
    public VO get(PK id) {
        VO result = (VO)orikaBeanMapper.convert(baseDao.get(id), entityVOClass);
        return result;
    }

    
    @SuppressWarnings("unchecked")
    public List<VO> getAll() {
        List<VO> result = new ArrayList<VO>();
        result = (List<VO>)orikaBeanMapper.convertList(baseDao.getAll(), entityVOClass);
        return result;
    }
    @SuppressWarnings("unchecked")
    public List<VO> getAll(BasePageSO so){
        List<VO> result = new ArrayList<VO>();
        result = (List<VO>)orikaBeanMapper.convertList(baseDao.getAll(so), entityVOClass);
        return result;
    }
    
    @SuppressWarnings("unchecked")
    public VO getBy(String fieldName, Object value) {
        VO result = (VO)orikaBeanMapper.convert(baseDao.getBy(fieldName, value), entityVOClass);
        return result;
    }

    
    @SuppressWarnings("unchecked")
    public List<VO> getByIds(List<PK> ids) {
        List<VO> result = new ArrayList<VO>();
        result = orikaBeanMapper.convertList(baseDao.getByIds(ids), entityVOClass);
        return result;
    }

    
    @SuppressWarnings("unchecked")
    public PageList<VO> getPageList(BasePageSO so) {
        PageList<VO> result = new PageList<VO>();
        result = orikaBeanMapper.convertPageList(baseDao.getPageList(so), entityVOClass);
        return result;
    }
    
    public void remove(PK id) {
        baseDao.remove(id);
    }
    
    public void remove(List<PK> ids) {
        baseDao.remove(ids);
    }
    
    @SuppressWarnings("unchecked")
	public VO create(VO vo) {
    	T t = (T)orikaBeanMapper.convert(vo, entityClass);
        VO result = (VO)orikaBeanMapper.convert(baseDao.create(t), entityVOClass);
        return result;
    }
    @SuppressWarnings("unchecked")
   	public  List<Long> batchCreate(List<VO> entityList) {
       	List<T>  t = (List<T>)orikaBeanMapper.convertList(entityList, entityClass);
       	List<Long> result = baseDao.batchCreate(t);
           return result;
       }
    @SuppressWarnings("unchecked")
	public VO update(VO vo) {
    	T t = (T)orikaBeanMapper.convert(vo, entityClass);
        VO result = (VO)orikaBeanMapper.convert(baseDao.update(t), entityVOClass);
        return result;
    }
    @SuppressWarnings("unchecked")
   	public  void batchUpdate(List<VO> entityList) {
       	List<T>  t = (List<T>)orikaBeanMapper.convertList(entityList, entityClass);
       	 baseDao.batchUpdate(t);
       }
    @SuppressWarnings("unchecked")
    public List<VO> getListBy(String fieldName, Object value) {
        List<VO> result = new ArrayList<VO>();
        result = orikaBeanMapper.convertList(baseDao.getListBy(fieldName, value), entityVOClass);
        return result;
    }
    
}

